﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NewRetail.Application.Components.WeChat.Configurations;
using NewRetail.Application.Components.WeChat.Services;
using NewRetail.Application.Components.WeChat.Services.HttpClients;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace NewRetail.Application.Components.WeChat.Menu.Services
{
    #region 微信菜单相关接口
    /// <summary>
    /// 微信菜单相关接口
    /// </summary>
    public interface IWeChatMenuService : IApplicationService
    {
        /// <summary>
        /// 创建微信菜单。
        /// </summary>
        /// <param name="memus"></param>
        /// <param name="appId"></param>
        /// <returns></returns>
        Task<(string, string)> CreateWeChatMenu(List<CgibinMenuCreateRequest.Types.Button> memus, string appId = null);

    }
    #endregion

    #region 微信菜单相关实现
    public class WeChatMenuService : ApplicationService, IWeChatMenuService
    {
        #region Field
        private readonly IWeChatApiHttpClientFactory _wechatApiHttpClientFactory;
        private readonly ILogger _logger;
        private readonly WeChatOptions _wechatOptions;
        private readonly IHttpContextAccessor _accessor;
        private readonly IWeChatAccessToken _weChatAccessToken;
        #endregion

        #region 构造函数
        public WeChatMenuService(IHttpContextAccessor accessor, IWeChatApiHttpClientFactory wechatApiHttpClientFactory,
            IWeChatAccessToken weChatAccessToken, IOptions<WeChatOptions> wechatOptions, ILogger<WeChatMenuService> logger)
        {
            _wechatApiHttpClientFactory = wechatApiHttpClientFactory;
            _logger = logger;
            _wechatOptions = wechatOptions.Value;
            _accessor = accessor;
            _weChatAccessToken = weChatAccessToken;
        }
        #endregion

        #region Implementation of ISignatureService

        #region 创建微信菜单
        /// <summary>
        /// 创建微信菜单
        /// </summary>
        /// <param name="memus"></param>
        /// <param name="appId"></param>
        /// <returns></returns>
        public async Task<(string, string)> CreateWeChatMenu(List<CgibinMenuCreateRequest.Types.Button> memus, string appId = null)
        {
            var errMsg = "";
            var result = "";
            try
            {
                //如果appId为空，那么就直接获取默认第一个
                if (string.IsNullOrEmpty(appId))
                    appId = _wechatOptions.Accounts?.FirstOrDefault().AppId;
                //获取accessToken对象
                var wechatAccessToken = await _weChatAccessToken.GetAccessTokenObject(appId);
                //创建一个http
                var wechatApiclient = _wechatApiHttpClientFactory.Create(appId);
                var requestInfo = new CgibinMenuCreateRequest()
                {
                    AccessToken = wechatAccessToken?.AccessToken,
                    ButtonList = memus
                };
                //请求获取数据
                var responseMenuInfo = await wechatApiclient.ExecuteCgibinMenuCreateAsync(requestInfo, cancellationToken: _accessor.HttpContext.RequestAborted);
                if (!responseMenuInfo.IsSuccessful())
                {
                    _logger.LogWarning(
                        "创建菜单失败（状态码：{0}，错误代码：{1}，错误描述：{2}）。",
                        responseMenuInfo.RawStatus, responseMenuInfo.ErrorCode, responseMenuInfo.ErrorMessage
                    );
                    errMsg = responseMenuInfo.ErrorMessage;
                    return (result, errMsg);
                }
                else
                    result = "创建成功";
            }
            catch (Exception e)
            {
                _logger.LogError("创建菜单异常：" + e.Message);
                errMsg = "创建菜单失败!" + e.Message;
            }
            return (result, errMsg);
        }
        #endregion

        #endregion

        #region private method


        #endregion
    }
    #endregion
}
